package com.yanqu.road.server.manager.activity.zhenhuan;

import com.yanqu.road.dao.impl.activity.zhenhuan.CrossZhenHuanPartyImpl;
import com.yanqu.road.dao.impl.activity.zhenhuan.CrossZhenHuanPartyJoinImpl;
import com.yanqu.road.dao.impl.activity.zhenhuan.CrossZhenHuanSecondUserImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanLevelConfig;
import com.yanqu.road.entity.activity.zhenhuan.secondProcess.CrossZhenHuanPartyData;
import com.yanqu.road.entity.activity.zhenhuan.secondProcess.CrossZhenHuanPartyJoinData;
import com.yanqu.road.entity.activity.zhenhuan.secondProcess.CrossZhenHuanSecondUserData;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.activity.zhenhuan.ZhenHuanSecondProcessConfig;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.ZhenHuanProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.sync.message.SyncResponse;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class CrossZhenHuanSecondActivity {
    private ActivityInfo activityInfo;
    //key=partyId 总的宴会数据 没同步过的
    private Map<Long, CrossZhenHuanPartyInfo> partyDataMap = new ConcurrentHashMap<>();
    //等级对应的宴会列表,没结束的会在这里
    private Map<Integer, List<CrossZhenHuanPartyInfo>> levelPartyListMap = new ConcurrentHashMap<>();
    //key=userId 玩家对应的没结束的宴会列表
    private Map<Long, List<Long>> userOpeningPartyIdListMap = new ConcurrentHashMap<>();

    private AtomicLong maxPartyId = new AtomicLong(1);

    private List<CrossZhenHuanPartyInfo> needSyncPartyList = new ArrayList<>();

    //key=userId
    private Map<Long, CrossZhenHuanSecondUserData> userMap = new ConcurrentHashMap<>();

    private ZhenHuanPartyComparator partyComparator = new ZhenHuanPartyComparator();

    public CrossZhenHuanSecondActivity(ZhenHuanSecondProcessConfig config) {
        this.activityInfo = config.getActivityInfo();
        loadDb();
    }

    public void loadDb() {
        Map<Long, Long> tempUserPrestigeMap = new ConcurrentHashMap<>();
        List<CrossZhenHuanPartyInfo> tempNeedSyncPartyList = new ArrayList<>();

        Map<Long, CrossZhenHuanSecondUserData> tempUserMap = new CrossZhenHuanSecondUserImpl().getCrossZhenHuanSecondUserData(activityInfo.getActivityId());
        Map<Long, CrossZhenHuanPartyData> tempPartDataMap = new CrossZhenHuanPartyImpl().getCrossZhenHuanPartyData(activityInfo.getActivityId());
        List<CrossZhenHuanPartyJoinData> tempJoinList = new CrossZhenHuanPartyJoinImpl().getCrossZhenHuanPartyJoinData(activityInfo.getActivityId());
        Map<Long, Map<Long, CrossZhenHuanPartyJoinData>> tempJoinMap = new HashMap<>();
        for (CrossZhenHuanPartyJoinData joinData : tempJoinList) {
            Long userPrestige = tempUserPrestigeMap.getOrDefault(joinData.getUserId(), 0L);
            userPrestige += joinData.getMatchPrestige();
            tempUserPrestigeMap.put(joinData.getUserId(), userPrestige);

            Map<Long, CrossZhenHuanPartyJoinData> map = tempJoinMap.get(joinData.getPartyId());
            if (map == null) {
                map = new HashMap<>();
                tempJoinMap.put(joinData.getPartyId(), map);
            }
            map.put(joinData.getUserId(), joinData);
        }


        Map<Long, CrossZhenHuanPartyInfo> tempPartyInfoMap = new ConcurrentHashMap<>();
        Map<Integer, List<CrossZhenHuanPartyInfo>> tempLevelPartyListMap = new ConcurrentHashMap<>();
        Map<Long, List<Long>> tempUserOpeningPartyIdListMap = new ConcurrentHashMap<>();

        long maxPartyId = 0;

        //把partyData和joinData组装成partyInfo,同时建立各种索引
        for (CrossZhenHuanPartyData partyData : tempPartDataMap.values()) {
            Long userPrestige = tempUserPrestigeMap.getOrDefault(partyData.getUserId(), 0L);
            userPrestige += partyData.getExtraPrestige();
            tempUserPrestigeMap.put(partyData.getUserId(), userPrestige);

            CrossZhenHuanPartyInfo partyInfo = new CrossZhenHuanPartyInfo(partyData, tempJoinMap.get(partyData.getPartyId()));
            maxPartyId = Math.max(maxPartyId, partyData.getPartyId());

            if (partyData.getSyncState() == 0) {
                tempPartyInfoMap.put(partyData.getPartyId(), partyInfo);
            }

            if (!partyInfo.isFinish()) {
                List<CrossZhenHuanPartyInfo> list = tempLevelPartyListMap.get(partyInfo.getPartyLevel());
                if (list == null) {
                    list = new ArrayList<>();
                    tempLevelPartyListMap.put(partyInfo.getPartyLevel(), list);
                }
                list.add(partyInfo);

                for (CrossZhenHuanPartyJoinData joinData : partyInfo.getJoinList()) {
                    List<Long> partyIdList = tempUserOpeningPartyIdListMap.get(joinData.getUserId());
                    if (partyIdList == null) {
                        partyIdList = new ArrayList<>();
                        tempUserOpeningPartyIdListMap.put(joinData.getUserId(), partyIdList);
                    }
                    partyIdList.add(partyInfo.getPartyId());
                }
            } else if (partyData.getSyncState() == 0) {//已结束未同步过的
                tempNeedSyncPartyList.add(partyInfo);
            }
        }

        this.partyDataMap = tempPartyInfoMap;
        this.levelPartyListMap = tempLevelPartyListMap;
        this.userOpeningPartyIdListMap = tempUserOpeningPartyIdListMap;
        this.maxPartyId.set(maxPartyId + 1);
        this.userMap = tempUserMap;
        this.needSyncPartyList = tempNeedSyncPartyList;
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public void save() {

        List<CrossZhenHuanPartyInfo> savePartyList = new ArrayList<>();
        synchronized (partyDataMap) {
            savePartyList.addAll(partyDataMap.values());
        }

        List<CrossZhenHuanPartyInfo> needRemoveList = new ArrayList<>();

        for (CrossZhenHuanPartyInfo partyInfo : savePartyList) {
            partyInfo.save();

            if (partyInfo.getPartyData().getSyncState() == 1) {
                //同步完的数据移出内存
                needRemoveList.add(partyInfo);
            }
        }

        for (CrossZhenHuanPartyInfo partyInfo : needRemoveList) {
            synchronized (partyDataMap) {
                partyDataMap.remove(partyInfo.getPartyId());
            }
        }

        List<CrossZhenHuanSecondUserData> saveUserList = new ArrayList<>();
        synchronized (userMap) {
            saveUserList.addAll(userMap.values());
        }

        for (CrossZhenHuanSecondUserData userData : saveUserList) {
            if (userData.isInsertOption()) {
                new CrossZhenHuanSecondUserImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new CrossZhenHuanSecondUserImpl().update(userData);
            }
        }
    }

    public CrossZhenHuanPartyInfo getPartyInfo(long partyId) {
        return partyDataMap.get(partyId);
    }

    /**
     * 我的宴会列表,开启中的默认在前面
     *
     * @param userId
     * @return
     */
    public List<Long> getUserPartyIdList(long userId) {
        List<Long> list = new ArrayList<>();
        if (userOpeningPartyIdListMap.containsKey(userId)) {
            List<Long> partyIds = userOpeningPartyIdListMap.get(userId);
            synchronized (partyIds) {
                list.addAll(partyIds);
            }
        }

        return list;
    }

    private void addUserOpeningPartyId(long userId, long partyId) {
        List<Long> partyIds = userOpeningPartyIdListMap.get(userId);
        if (partyIds == null) {
            synchronized (userOpeningPartyIdListMap) {
                partyIds = userOpeningPartyIdListMap.get(userId);
                if (partyIds == null) {
                    partyIds = new ArrayList<>();
                    userOpeningPartyIdListMap.put(userId, partyIds);
                }
            }
        }
        synchronized (partyIds) {
            partyIds.add(partyId);
        }
    }

    private void removeUserOpeningPartyId(long userId, long partyId) {
        List<Long> partyIds = userOpeningPartyIdListMap.get(userId);
        if (partyIds == null) {
            return;
        }
        synchronized (partyIds) {
            partyIds.remove(partyId);
        }
    }

    /**
     * 找某个玩家开的宴会数量
     * @param userId
     * @return
     */
    public int getUserOpenPartyNum(long userId) {
        int num = 0;
        List<Long> userPartyIdList = getUserPartyIdList(userId);//有该玩家的所有宴会
        for (Long partyId : userPartyIdList) {
            CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
            if (partyInfo == null) {
                continue;
            }
            if (partyInfo.isFinish()) {
                continue;
            }
            if (partyInfo.getPartyData().getUserId() != userId) {
                continue;
            }
            num++;
        }
        return num;
    }

    public int getUserOpenPartyNumExcludeJoin(long userId, long joinUserId) {
        int num = 0;
        List<Long> userPartyIdList = getUserPartyIdList(userId);//有该玩家的所有宴会
        for (Long partyId : userPartyIdList) {
            CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
            if (partyInfo == null) {
                continue;
            }
            if (partyInfo.isFinish()) {
                continue;
            }
            if (partyInfo.getPartyData().getUserId() != userId) {
                continue;
            }

            if (partyInfo.isUserJoin(joinUserId)) {
                continue;
            }
            num++;
        }
        return num;
    }

    public ZhenHuanSecondProcessConfig getConfig() {
        return CrossZhenHuanConfigMgr.getSecondProcessConfig(activityInfo.getActivityId());
    }

    public List<CrossZhenHuanPartyInfo> getPartyListByLevel(int level) {
        List<CrossZhenHuanPartyInfo> list = new ArrayList<>();
        synchronized (levelPartyListMap) {
            if (levelPartyListMap.containsKey(level)) {
                list.addAll(levelPartyListMap.get(level));
            }
        }
        return list;
    }

    public List<CrossZhenHuanPartyInfo> getPartyListByLevel(int level, boolean isNeedFull, long excludeUserId) {
        List<CrossZhenHuanPartyInfo> list = new ArrayList<>();
        List<CrossZhenHuanPartyInfo> resultList = new ArrayList<>();
        synchronized (levelPartyListMap) {
            if (levelPartyListMap.containsKey(level)) {
                list.addAll(levelPartyListMap.get(level));
            }
        }
        ZhenHuanSecondProcessConfig config = getConfig();

        for (CrossZhenHuanPartyInfo partyInfo : list) {
            if (partyInfo.isFinish()) {
                continue;
            }

            if (isNeedFull) {
                if (!partyInfo.isFull(config.getPartyCanJoinNum())) {
                    continue;
                }
            }

            if (partyInfo.isUserJoin(excludeUserId)) {
                continue;
            }

            if (partyInfo.isTimeEnd()) {
                continue;
            }

            partyInfo.setSortPrestige(partyInfo.getPartyData().getExtraPrestige());
            partyInfo.setSortJoinNum(partyInfo.getJoinNum());
            resultList.add(partyInfo);
        }
        return resultList;
    }

    public void sendAllPartyListMsg(long userId, long serverId, ZhenHuanProto.ZhenHuanSecondProcessAllPartyListReqMsg reqMsg) {
        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return;
        }
        int partyLevel = reqMsg.getPartyLevel();
        int statusNeed = reqMsg.getStatusNeed();//0全部 1只要满座的
        int pageNo = reqMsg.getPage();
        int pageSize = reqMsg.getPageSize();
        int rangeType = reqMsg.getRangeType();//范围类型 1 我举办的 2 我加入的 3 未参与的

        boolean isNeedFull = statusNeed == 0 ? false : true;

        List<CrossZhenHuanPartyInfo> resultPartyInfoList = new ArrayList<>();

        //页数从1开始
        int beginIndex = (pageNo - 1) * pageSize;
        int endIndex = pageNo * pageSize;
        int searchAmount = 0;

        if (rangeType == 1) {
            List<CrossZhenHuanPartyInfo> userOwnPartyList = new ArrayList<>();
            List<Long> userPartyIdList = getUserPartyIdList(userId);
            for (Long partyId : userPartyIdList) {
                CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
                if (partyInfo == null) {
                    continue;
                }
                if (partyInfo.isFinish()) {
                    continue;
                }

                if (partyInfo.getPartyData().getUserId() != userId) {//不是我举办的
                    continue;
                }

                if (partyLevel != 0 && partyInfo.getPartyData().getLevel() != partyLevel) {
                    continue;
                }
                if (isNeedFull && !partyInfo.isFull(config.getPartyCanJoinNum())) {
                    continue;
                }

                partyInfo.setSortPrestige(partyInfo.getPartyData().getExtraPrestige());
                partyInfo.setSortJoinNum(partyInfo.getJoinNum());
                userOwnPartyList.add(partyInfo);
            }

            /*
            优先展示玩家举办的茶话会
            1	玩家同时举办多个茶话会时，威信奖励数值高的排在前面
            2	威信奖励数值相同时，参与人数更少的排在前面
            3	参与人数也相同时，举办时间早的排在前面
            */
            userOwnPartyList.sort(partyComparator);

            for (CrossZhenHuanPartyInfo partyInfo : userOwnPartyList) {
                if (searchAmount < beginIndex) {
                    searchAmount++;
                    continue;
                }
                searchAmount++;

                resultPartyInfoList.add(partyInfo);

                if (searchAmount >= endIndex) {
                    break;
                }
            }
        } else if (rangeType == 2) {
            /*再展示玩家参与中的茶话会
            1	同时参与多个茶话会时，威信奖励数值高的排在前面
            2	威信奖励数值相同时，参与人数更少的排在前面
            3	参与人数也相同时，举办时间早的排在前面
             */
            List<CrossZhenHuanPartyInfo> userJoinPartyList = new ArrayList<>();
            List<Long> userPartyIdList = getUserPartyIdList(userId);
            for (Long partyId : userPartyIdList) {
                CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
                if (partyInfo == null) {
                    continue;
                }
                if (partyInfo.isFinish()) {
                    continue;
                }

                if (partyInfo.getPartyData().getUserId() == userId) {//是我举办的
                    continue;
                }

                if (partyLevel != 0 && partyInfo.getPartyData().getLevel() != partyLevel) {
                    continue;
                }
                if (isNeedFull && !partyInfo.isFull(config.getPartyCanJoinNum())) {
                    continue;
                }

                partyInfo.setSortPrestige(partyInfo.getPartyData().getExtraPrestige());
                partyInfo.setSortJoinNum(partyInfo.getJoinNum());
                userJoinPartyList.add(partyInfo);
            }

            userJoinPartyList.sort(partyComparator);

            for (CrossZhenHuanPartyInfo partyInfo : userJoinPartyList) {
                if (searchAmount < beginIndex) {
                    searchAmount++;
                    continue;
                }
                searchAmount++;

                resultPartyInfoList.add(partyInfo);

                if (searchAmount >= endIndex) {
                    break;
                }
            }

        } else if (rangeType == 3) {//未参与的
            if (partyLevel == 0) {
                int maxLevel = config.getMaxLevel();
                //从最大的等级开始,往下找
                for (int level = maxLevel; level > 0; level--) {
                    List<CrossZhenHuanPartyInfo> partyListByLevel = getPartyListByLevel(level, isNeedFull, userId);
                    partyListByLevel.sort(partyComparator);

                    if (searchAmount < beginIndex) {
                        searchAmount += partyListByLevel.size();
                        continue;
                    }

                    for (int i = 0; i < partyListByLevel.size(); i++) {
                        CrossZhenHuanPartyInfo partyInfo = partyListByLevel.get(i);
                        if (searchAmount < beginIndex) {
                            searchAmount++;
                            continue;
                        }
                        searchAmount++;

                        resultPartyInfoList.add(partyInfo);

                        if (searchAmount >= endIndex) {
                            break;
                        }
                    }

                    if (searchAmount >= endIndex) {
                        break;
                    }
                }
            } else {
                List<CrossZhenHuanPartyInfo> partyListByLevel = getPartyListByLevel(partyLevel, isNeedFull, userId);
                partyListByLevel.sort(partyComparator);
                for (int i = 0; i < partyListByLevel.size(); i++) {
                    CrossZhenHuanPartyInfo partyInfo = partyListByLevel.get(i);

                    if (searchAmount < beginIndex) {
                        searchAmount++;
                        continue;
                    }
                    searchAmount++;

                    resultPartyInfoList.add(partyInfo);

                    if (searchAmount >= endIndex) {
                        break;
                    }
                }
            }
        }


        ZhenHuanProto.ZhenHuanSecondProcessAllPartyListRespMsg.Builder clientMsg = ZhenHuanProto.ZhenHuanSecondProcessAllPartyListRespMsg.newBuilder();
        clientMsg.setRet(0);
        clientMsg.setPage(pageNo);
        clientMsg.setPageSize(pageSize);
        clientMsg.setMyOpenNum(getUserOpenPartyNum(userId));
        clientMsg.setRangeType(rangeType);

        for (CrossZhenHuanPartyInfo partyInfo : resultPartyInfoList) {
            ZhenHuanProto.ZhenHuanSecondProcessPartySimpleTemp simpleTemp = parsePartySimpleInfo(partyInfo, userId);
            clientMsg.addPartyList(simpleTemp);
        }

        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(ClientProtocol.U_ZHENHUAN_SECOND_PROCESS_ALL_PARTY_LIST, clientMsg));
    }

    public ZhenHuanProto.ZhenHuanSecondProcessPartySimpleTemp parsePartySimpleInfo(CrossZhenHuanPartyInfo partyInfo, long reqUserId) {
        ZhenHuanProto.ZhenHuanSecondProcessPartySimpleTemp.Builder builder = ZhenHuanProto.ZhenHuanSecondProcessPartySimpleTemp.newBuilder();
        builder.setPartyId(partyInfo.getPartyId());
        builder.setLevel(partyInfo.getPartyLevel());

        long openUserId = partyInfo.getPartyData().getUserId();
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(openUserId);
        builder.setPlayerName(userBaseInfo.getNickName());
        builder.setDecoration(userBaseInfo.getDecoration());
        builder.setUserId(openUserId);
        builder.setIsJoin(partyInfo.isUserJoin(reqUserId) ? 1 : 0);
        builder.setEndTime(partyInfo.getPartyEndTime());
        builder.setInNum(partyInfo.getJoinNum());
        builder.setOpenServerId(userBaseInfo.getServerId());
        builder.setExtraPrestige(partyInfo.getPartyData().getExtraPrestige());

        return builder.build();
    }

    public ZhenHuanProto.ZhenHuanSecondProcessPartyDetailRespMsg.Builder getPartyDetailInfo(long partyId) {
        ZhenHuanProto.ZhenHuanSecondProcessPartyDetailRespMsg.Builder clientMsg = ZhenHuanProto.ZhenHuanSecondProcessPartyDetailRespMsg.newBuilder();
        clientMsg.setRet(0);

        CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
        if (partyInfo == null) {
            return clientMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_PARTY_NOT_FOUND);
        }

        clientMsg.setDetailInfo(parsePartyDetailInfo(partyInfo));
        return clientMsg;
    }

    public ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp.Builder parsePartyDetailInfo(CrossZhenHuanPartyInfo partyInfo) {
        ZhenHuanSecondProcessConfig config = getConfig();

        ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp.Builder detailMsg = ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp.newBuilder();
        detailMsg.setPartyId(partyInfo.getPartyId());
        detailMsg.setLevel(partyInfo.getPartyLevel());
        detailMsg.setEndTime(partyInfo.getPartyEndTime());
        detailMsg.setOpenLevel(partyInfo.getPartyData().getLevel());

        long openUserId = partyInfo.getPartyData().getUserId();
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(openUserId);
        detailMsg.setPlayerName(userBaseInfo.getNickName());
        detailMsg.setDecoration(userBaseInfo.getDecoration());
        detailMsg.setUserId(openUserId);
        detailMsg.setOpenServerId(userBaseInfo.getServerId());
        detailMsg.setExtraPrestige(partyInfo.getPartyData().getExtraPrestige());

        for (CrossZhenHuanPartyJoinData joinData : partyInfo.getJoinList()) {
            ZhenHuanLevelConfig levelConfig = config.getLevelConfig(joinData.getUserLevel());

            ZhenHuanProto.ZhenHuanSecondProcessPartyPlayerTemp.Builder joinTemp = ZhenHuanProto.ZhenHuanSecondProcessPartyPlayerTemp.newBuilder();
            joinTemp.setUserId(joinData.getUserId());
            joinTemp.setIsNpc(joinData.getIsNpc() == 1);
            if (joinData.getIsNpc() != 1) {
                UserBaseInfo joinUserBaseInfo = CrossUserMgr.getUserBaseInfo(joinData.getUserId());
                joinTemp.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(joinUserBaseInfo));
            }
            joinTemp.setLevel(joinData.getUserLevel());
            joinTemp.setPos(joinData.getPos());
            joinTemp.setFinishPrestige(joinData.getMatchPrestige());
            joinTemp.setJoinPrestige(levelConfig.getUseInvitationPrestige());

            if (joinData.getPos() == 1) {
                joinTemp.setSharePrestige(levelConfig.getSharePrestige() * config.getOpenMultiPrestige());
            } else {
                joinTemp.setJoinPrestige(levelConfig.getUseInvitationPrestige());
            }

            joinTemp.setUserPrestige(joinData.getUserPrestige());

            detailMsg.addPlayerList(joinTemp);
        }
        return detailMsg;
    }

    public ZhenHuanProto.ZhenHuanSecondProcessJoinPartyRespMsg.Builder joinParty(long partyId, long userId, int userLevel, long userPrestige, int pos, long targetUserId) {
        ZhenHuanProto.ZhenHuanSecondProcessJoinPartyRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessJoinPartyRespMsg.newBuilder();
        respMsg.setRet(0);

        CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
        if (partyInfo == null) {
            return respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_PARTY_NOT_FOUND);
        }

        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_CONFIG_NOT_FOUND);
        }

        CrossZhenHuanJoinResult joinResult = partyInfo.joinUser(pos, userId, userLevel, userPrestige, targetUserId, config);
        if (joinResult.getRet() != 0) {
            return respMsg.setRet(joinResult.getRet());
        }

        //加入玩家的宴会列表
        addUserOpeningPartyId(userId, partyId);

        respMsg.setDetailInfo(parsePartyDetailInfo(partyInfo));
        respMsg.setTargetId(targetUserId);
        respMsg.setPos(pos);
        respMsg.setTargetLevel(joinResult.getDefendLevel());
        respMsg.setTargetPrestige(joinResult.getDefendPrestige());

        if (targetUserId > 0 && !config.isNpc(targetUserId)) {
            //被踢移出玩家的宴会列表
            removeUserOpeningPartyId(targetUserId, partyId);

            UserBaseInfo targetUserBaseInfo = CrossUserMgr.getUserBaseInfo(targetUserId);
            if (targetUserBaseInfo != null) {
                respMsg.setKickUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(targetUserBaseInfo));

                //通知到被踢玩家所在服
                ZhenHuanProto.CrossZhenHuanSecondProcessNewKickRecordRespMsg.Builder kickMsg = ZhenHuanProto.CrossZhenHuanSecondProcessNewKickRecordRespMsg.newBuilder();
                kickMsg.setActivityId(activityInfo.getActivityId());
                kickMsg.setPartyId(partyInfo.getPartyId());
                kickMsg.setKickTime(DateHelper.getCurrentTime());
                kickMsg.setKickUserId(userId);
                kickMsg.setBeKickUserId(targetUserId);
                kickMsg.setAttackLevel(userLevel);
                kickMsg.setAttackPrestige(userPrestige);
                kickMsg.setPos(pos);
                kickMsg.setDefendLevel(joinResult.getDefendLevel());
                kickMsg.setDefendPrestige(joinResult.getDefendPrestige());
                kickMsg.setOpenUserId(partyInfo.getPartyData().getUserId());
                kickMsg.setPartyLevel(partyInfo.getPartyLevel());
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(partyInfo.getPartyData().getUserId());
                if (userBaseInfo != null) {
                    kickMsg.setOpenUserName(userBaseInfo.getNickName());
                }
                MessageHelper.sendPacket(targetUserBaseInfo.getServerId(), targetUserId,
                        YanQuMessageUtils.buildMessage(GameProtocol.S_ZHENHUAN_SECOND_PROCESS_NEW_KICK_RECORD_CROSS_BACK, kickMsg));
            }
        }

        partyInfo.calcExtraPrestige(config);

        CrossZhenHuanSecondUserData userData = getUserDataNewIfNull(userId);
        if (userLevel > userData.getLevel()) {
            userData.setLevel(userLevel);
        }
        if (userPrestige > userData.getPrestige()) {
            userData.setPrestige(userPrestige);
        }


        return respMsg;
    }

    public ZhenHuanProto.ZhenHuanSecondProcessOpenPartyRespMsg.Builder openParty(long userId, int userLevel) {
        ZhenHuanProto.ZhenHuanSecondProcessOpenPartyRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessOpenPartyRespMsg.newBuilder();
        respMsg.setRet(0);

        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_CONFIG_NOT_FOUND);
        }

        int userOpenPartyNum = getUserOpenPartyNum(userId);
        if (userOpenPartyNum >= config.getMaxOpenNum()) {
            return respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_OPEN_PARTY_NUM_LIMIT);
        }

        long partyId = maxPartyId.getAndIncrement();
        GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(config.getPartyGoodsId());
        if (goodsInfo == null) {
            return respMsg.setRet(GameErrorCode.E_BAG_ITEM_NO_EXIST);
        }

        CrossZhenHuanPartyData partyData = new CrossZhenHuanPartyData(activityInfo.getActivityId(), partyId);
        partyData.setUserId(userId);
        partyData.setLevel(userLevel);
        partyData.setOpenTime(DateHelper.getCurrentTime());
        partyData.setEndTime(config.calcPartyEndTime(partyData.getLevel(), partyData.getOpenTime()));

        CrossZhenHuanPartyJoinData joinData = new CrossZhenHuanPartyJoinData(activityInfo.getActivityId(), partyId, 1, userId);
        joinData.setJoinTime(partyData.getOpenTime());
        joinData.setUserLevel(userLevel);

        Map<Long, CrossZhenHuanPartyJoinData> joinMap = new HashMap<>();
        joinMap.put(joinData.getUserId(), joinData);
        CrossZhenHuanPartyInfo partyInfo = new CrossZhenHuanPartyInfo(partyData, joinMap);

        partyInfo.calcExtraPrestige(config);

        synchronized (partyDataMap) {
            partyDataMap.put(partyId, partyInfo);
        }

        synchronized (levelPartyListMap) {
            List<CrossZhenHuanPartyInfo> partyList = levelPartyListMap.get(partyInfo.getPartyLevel());
            if (partyList == null) {
                partyList = new ArrayList<>();
                levelPartyListMap.put(partyInfo.getPartyLevel(), partyList);
            }
            partyList.add(partyInfo);
        }

        addUserOpeningPartyId(userId, partyId);

        ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp.Builder detailInfo = parsePartyDetailInfo(partyInfo);
        respMsg.setDetailInfo(detailInfo);

        Property reward = new Property();
        ZhenHuanLevelConfig levelConfig = config.getLevelConfig(userLevel);
        if (levelConfig != null) {
            reward.addProperty(config.getExchangeItemId(), levelConfig.getOpenPartyPrestige());
            addUserPrestige(userId, levelConfig.getOpenPartyPrestige());
        }
        respMsg.setReward(reward.toHelperString());
        respMsg.setMyOpenNum(getUserOpenPartyNum(userId));

        CrossZhenHuanSecondUserData userData = getUserDataNewIfNull(userId);
        synchronized (userData) {
            userData.setLevel(userLevel);
        }

        return respMsg;
    }

    public ZhenHuanProto.ZhenHuanSecondProcessMyPartyListRespMsg.Builder getMyPartyListMsg(long userId, int pageNo, int pageSize, int tapType) {
        ZhenHuanProto.ZhenHuanSecondProcessMyPartyListRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessMyPartyListRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setPage(pageNo);
        respMsg.setPageSize(pageSize);
        respMsg.setTapType(tapType);// 0我举办 1我参与
        respMsg.setPartyStatus(1);

        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_CONFIG_NOT_FOUND);
        }

        List<Long> userPartyIdList = getUserPartyIdList(userId);
        if (userPartyIdList == null) {
            return respMsg;
        }

        int startIndex = (pageNo - 1) * pageSize;
        int endIndex = pageNo * pageSize;
        if (startIndex >= userPartyIdList.size()) {
            return respMsg;
        }

        int searchCount = 0;

        for (Long partyId : userPartyIdList) {
            CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
            if (partyInfo == null) {
                continue;
            }
            if (tapType == 0) {//我举办的
                if (partyInfo.getPartyData().getUserId() != userId) {
                    continue;
                }
            }

            if (tapType == 1) {//我参与的
                if (partyInfo.getPartyData().getUserId() == userId) {
                    continue;
                }
            }

            if (searchCount < startIndex) {
                searchCount++;
                continue;
            }
            searchCount++;

            CrossZhenHuanPartyJoinData joinData = partyInfo.getJoinDataByUserId(userId);
            if (joinData == null) {
                continue;
            }

            ZhenHuanProto.ZhenHuanSecondProcessMyPartyTemp.Builder myPartyTemp = ZhenHuanProto.ZhenHuanSecondProcessMyPartyTemp.newBuilder();
            ZhenHuanProto.ZhenHuanSecondProcessPartySimpleTemp simpleTemp = parsePartySimpleInfo(partyInfo, userId);
            myPartyTemp.setPartyInfo(simpleTemp);
            myPartyTemp.setReward(config.parsePrestigeRewardString(joinData.getMatchPrestige()));
            myPartyTemp.setIsGet(false);

            respMsg.addMyParty(myPartyTemp);

            if (searchCount >= endIndex) {
                break;
            }
        }

        return respMsg;
    }

    public ZhenHuanProto.ZhenHuanSecondProcessKickRecordRespMsg.Builder parseKickUserRecordMsg(List<ZhenHuanProto.GetCrossKickRecordReqTemp> reqList) {
        ZhenHuanProto.ZhenHuanSecondProcessKickRecordRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessKickRecordRespMsg.newBuilder();
        respMsg.setRet(0);

        for (ZhenHuanProto.GetCrossKickRecordReqTemp temp : reqList) {

            ZhenHuanProto.ZhenHuanSecondProcessKickRecordTemp.Builder recordTemp = ZhenHuanProto.ZhenHuanSecondProcessKickRecordTemp.newBuilder();
            recordTemp.setPartyId(temp.getPartyId());
            recordTemp.setLevel(temp.getLevel());

            recordTemp.setOpenUserName(temp.getOpenUserName());
            recordTemp.setOpenUserId(temp.getOpenUserId());

            recordTemp.setKickTime(temp.getKickTime());
            recordTemp.setKickUserId(temp.getKickUserId());

            UserBaseInfo kickUserBaseInfo = CrossUserMgr.getUserBaseInfo(recordTemp.getKickUserId());
            recordTemp.setKickUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(kickUserBaseInfo));

            respMsg.addKickRecordList(recordTemp);
        }

        return respMsg;
    }

    public void updateUserPartyJoinLevel(long userId, int userLevel, long userPrestige) {
        ZhenHuanSecondProcessConfig config = getConfig();

        List<Long> userPartyIdList = getUserPartyIdList(userId);
        for (Long partyId : userPartyIdList) {
            CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
            if (partyInfo == null) {
                continue;
            }

            //需求变动,开宴的人也要更新,需求再变动,开宴的人不更新
            if (partyInfo.getPartyData().getUserId() == userId) {
                continue;
            }

            if (partyInfo.getPartyData().getFinishTime() != 0) {
                continue;
            }

            int oldPartyLevel = partyInfo.getPartyLevel();

            partyInfo.updateJoinLevel(userId, userLevel, userPrestige, config);

            int newPartyLevel = partyInfo.getPartyLevel();

//            if (oldPartyLevel != newPartyLevel) {//需求变动后,等级不会有变化了,无视
//                synchronized (levelPartyListMap) {
//                    List<CrossZhenHuanPartyInfo> partyInfos = levelPartyListMap.get(oldPartyLevel);
//                    if (partyInfos != null) {
//                        partyInfos.remove(partyInfo);
//                    }
//
//                    partyInfos = levelPartyListMap.get(newPartyLevel);
//                    if (partyInfos == null) {
//                        partyInfos = new ArrayList<>();
//                        levelPartyListMap.put(newPartyLevel, partyInfos);
//                    }
//                    partyInfos.add(partyInfo);
//                }
//                partyInfo.calcExtraPrestige(config);
//            }
        }

        CrossZhenHuanSecondUserData userData = getUserDataNewIfNull(userId);
        if (userLevel > userData.getLevel()) {//只会变大,防止先后问题
            userData.setLevel(userLevel);
        }
        if (userPrestige > userData.getPrestige()) {
            userData.setPrestige(userPrestige);
        }
    }

    public void initUserData(long userId, int userLevel, long userPrestige) {
        CrossZhenHuanSecondUserData userData = getUserDataNewIfNull(userId);
        if (userLevel > userData.getLevel()) {//只会变大,防止先后问题
            userData.setLevel(userLevel);
        }
        if (userPrestige > userData.getPrestige()) {
            userData.setPrestige(userPrestige);
        }
    }

    public CrossZhenHuanSecondUserData getUserDataNewIfNull(long userId) {
        CrossZhenHuanSecondUserData crossZhenHuanSecondUserData = userMap.get(userId);
        if (crossZhenHuanSecondUserData == null) {
            synchronized (userMap) {
                crossZhenHuanSecondUserData = userMap.get(userId);
                if (crossZhenHuanSecondUserData == null) {
                    crossZhenHuanSecondUserData = new CrossZhenHuanSecondUserData(activityInfo.getActivityId(), userId);
                    userMap.put(userId, crossZhenHuanSecondUserData);
                }
            }
        }
        return crossZhenHuanSecondUserData;
    }

    public CrossZhenHuanSecondUserData getUserDataOnlyGet(long userId) {
        return userMap.get(userId);
    }

    public void checkPartyEndTask() {
        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return;
        }

        List<CrossZhenHuanPartyInfo> allPartyList = new ArrayList<>();
        synchronized (partyDataMap) {
            allPartyList.addAll(partyDataMap.values());
        }
        List<CrossZhenHuanPartyInfo> endPartyList = new ArrayList<>();

        for (CrossZhenHuanPartyInfo partyInfo : allPartyList) {
            if (partyInfo.isFinish()){
                continue;
            }
            if (!partyInfo.isTimeEnd()) {
                continue;
            }
            //判断是否有空位,有空位填NPC人进入抢座时间,需求改了机器人填完不进入抢座时间
            partyInfo.fillNpc(config);

            endPartyList.add(partyInfo);
        }

        //结束的宴会从等级列表中移除
        for (CrossZhenHuanPartyInfo partyInfo : endPartyList) {
            endParty(partyInfo);
        }

    }

    /**
     * 茶话会结束,同步到游戏服，移出内存
     *
     * @param partyInfo
     */
    private void endParty(CrossZhenHuanPartyInfo partyInfo) {
        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return;
        }
        partyInfo.endParty(config);

        synchronized (levelPartyListMap) {
            List<CrossZhenHuanPartyInfo> partyList = levelPartyListMap.get(partyInfo.getPartyLevel());
            if (partyList != null) {
                partyList.remove(partyInfo);
            }
        }

        synchronized (userOpeningPartyIdListMap) {
            List<CrossZhenHuanPartyJoinData> joinList = partyInfo.getJoinList();
            for (CrossZhenHuanPartyJoinData joinData : joinList) {
                long userId = joinData.getUserId();
                List<Long> partyIdList = userOpeningPartyIdListMap.get(userId);
                if (partyIdList != null) {
                    partyIdList.remove(partyInfo.getPartyId());
                }

                addUserPrestige(joinData.getUserId(), joinData.getMatchPrestige());
            }
        }

        synchronized (needSyncPartyList) {
            needSyncPartyList.add(partyInfo);
        }
    }

    /**
     * 同步已结束的茶话会到游戏服
     */
    public void syncEndPartyTask() {
        ZhenHuanSecondProcessConfig config = getConfig();
        if (config == null) {
            return;
        }

        List<CrossZhenHuanPartyInfo> syncPartyList = new ArrayList<>();
        synchronized (needSyncPartyList) {
            syncPartyList.addAll(needSyncPartyList);
            needSyncPartyList.clear();
        }

        //要同步到那些游戏服
        Map<Long, Map<Long, CrossZhenHuanPartyInfo>> serverPartyMap = new HashMap<>();
        for (CrossZhenHuanPartyInfo partyInfo : syncPartyList) {
            if (partyInfo.getPartyData().getSyncState() == 1) {
                continue;
            }

            List<CrossZhenHuanPartyJoinData> joinList = partyInfo.getJoinList();
            for (CrossZhenHuanPartyJoinData joinData : joinList) {
                if (joinData.getIsNpc() == 1) {//npc不需要同步
                    continue;
                }
                long userId = joinData.getUserId();
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
                if (userBaseInfo == null) {
                    continue;
                }
                long serverId = userBaseInfo.getServerId();
                Map<Long, CrossZhenHuanPartyInfo> tempMap = serverPartyMap.get(serverId);
                if (tempMap == null) {
                    tempMap = new HashMap<>();
                    serverPartyMap.put(serverId, tempMap);
                }
                tempMap.put(partyInfo.getPartyId(), partyInfo);
            }
        }

        for (Map.Entry<Long, Map<Long, CrossZhenHuanPartyInfo>> entry : serverPartyMap.entrySet()) {
            Long serverId = entry.getKey();

            ZhenHuanProto.CrossZhenHuanSecondProcessFinishPartySyncMsg.Builder syncMsg = ZhenHuanProto.CrossZhenHuanSecondProcessFinishPartySyncMsg.newBuilder();
            syncMsg.setActivityId(activityInfo.getActivityId());

            for (CrossZhenHuanPartyInfo partyInfo : entry.getValue().values()) {
                ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp.Builder detailBuilder = parsePartyDetailInfo(partyInfo);
                syncMsg.addPartyDetailList(detailBuilder);
            }
            CompletableFuture<SyncResponse> future = MessageHelper.sendToGameServer(serverId, GameProtocol.S_ZHENHUAN_SECOND_PROCESS_PARTY_FINISH_CROSS_BACK, syncMsg.getActivityId(), 0, syncMsg, null);
            future.thenAccept((SyncResponse resp) -> {
                if (resp.getErrorCode() != 0) {
                    CrossZhenHuanMgr.getLogger().error("syncEndPartyTask error, serverId:{}, errorCode:{}", serverId, resp.getErrorCode());
                    for (ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp detailTemp : syncMsg.getPartyDetailListList()) {
                        long partyId = detailTemp.getPartyId();
                        CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
                        if (partyInfo != null && partyInfo.getPartyData().getSyncState() == 0) {
                            synchronized (needSyncPartyList) {
                                needSyncPartyList.add(partyInfo);
                            }
                        }
                    }
                } else {
                    for (ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp detailTemp : syncMsg.getPartyDetailListList()) {
                        long partyId = detailTemp.getPartyId();
                        CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
                        if (partyInfo != null && partyInfo.getPartyData().getSyncState() == 0) {
                            partyInfo.getPartyData().setSyncState(1);
                        }
                    }
                }
            });
        }
    }

    private void addUserPrestige(long userId, long addPrestige) {

    }

    public String debug(String params) {
        return "";
    }

    public void sendUserInfoList(long userId, long serverId, ZhenHuanProto.CrossZhenHuanSecondProcessGetUserListReqMsg reqMsg) {
        ZhenHuanProto.ZhenHuanSecondProcessRelationListRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessRelationListRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setTapType(reqMsg.getTapType());

        for (Long targetUserId : reqMsg.getUserIdListList()) {
            CrossZhenHuanSecondUserData userData = getUserDataOnlyGet(targetUserId);
            if (userData == null) {
                continue;
            }

            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(targetUserId);
            if (userBaseInfo == null) {
                continue;
            }

            ZhenHuanProto.ZhenHuanSecondProcessRelationTemp.Builder tempBuilder = ZhenHuanProto.ZhenHuanSecondProcessRelationTemp.newBuilder();
            tempBuilder.setUserId(targetUserId);
            tempBuilder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            tempBuilder.setLevel(userData.getLevel());
            tempBuilder.setPrestige(userData.getPrestige());
            tempBuilder.setJoinAmount(0);//暂时不用,等有需求再说
            tempBuilder.setPartyOpen(getUserOpenPartyNumExcludeJoin(targetUserId, userId)); //要自己没加入过的

            respMsg.addRelationList(tempBuilder);
        }

        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(ClientProtocol.U_ZHENHUAN_SECOND_PROCESS_RELATION_LIST, respMsg));
    }

    public void findUserInfo(long userId, long serverId, long targetServerId, long targetAliasId) {
        ZhenHuanProto.ZhenHuanSecondProcessFindUserRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessFindUserRespMsg.newBuilder();
        respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_NOT_ABLE);

        for (CrossZhenHuanSecondUserData userData : userMap.values()) {//这个晋级后不会变动了，不用锁
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getUserId());
            if (userBaseInfo == null) {
                continue;
            }
            if (userBaseInfo.getUserAliasId() == targetAliasId && userBaseInfo.getServerId() == targetServerId){
                respMsg.setRet(0);
                respMsg.setTargetUserId(userData.getUserId());
                respMsg.setTargetUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                respMsg.setTargetUserLevel(userData.getLevel());
                respMsg.setPartyOpen(getUserOpenPartyNumExcludeJoin(userData.getUserId(), userId));
                break;
            }
        }

        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(ClientProtocol.U_ZHENHUAN_SECOND_PROCESS_FIND_USER, respMsg));
    }

    public void nextParty(long userId, long serverId, ZhenHuanProto.ZhenHuanSecondProcessNextPartyReqMsg reqMsg) {
        ZhenHuanProto.ZhenHuanSecondProcessNextPartyRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanSecondProcessNextPartyRespMsg.newBuilder();
        respMsg.setRet(0);

        int levelNeed = reqMsg.getPartyLevel();
        long targetUserId = reqMsg.getTargetUserId();
        int statusNeed = reqMsg.getStatusNeed();
        boolean isNeedFull = statusNeed == 1;
        long nowPartyId = reqMsg.getNowPartyId();

        ZhenHuanSecondProcessConfig config = getConfig();

        CrossZhenHuanPartyInfo findPartyInfo = null;

        if (targetUserId == 0) {//在全部宴会里找下一场
            if (levelNeed == 0) {//全部宴会
                int maxLevel = config.getMaxLevel();
                int nowPartyLevel = 0;
                if (nowPartyId > 0) {
                    CrossZhenHuanPartyInfo partyInfo = getPartyInfo(nowPartyId);
                    if (partyInfo != null) {
                        nowPartyLevel = partyInfo.getPartyLevel();
                    }
                }

                //从最大的等级开始,往下找
                for (int level = maxLevel; level > 0; level--) {
                    List<CrossZhenHuanPartyInfo> partyList = getPartyListByLevel(level, isNeedFull, userId);
                    if (!partyList.isEmpty() && findPartyInfo == null) {
                        findPartyInfo = partyList.get(0); //先默认第一场
                    }
                    if (level < nowPartyLevel) {//找到nowParty的下一个等级了,有就直接给了
                        if (!partyList.isEmpty()) {
                            findPartyInfo = partyList.get(0);
                            break;
                        }
                    }
                    //找到nowPartyId的后面一场
                    if (nowPartyId > 0) {
                        boolean isFind = false;
                        for (int i = 0; i < partyList.size(); i++) {
                            CrossZhenHuanPartyInfo partyInfo = partyList.get(i);
                            if (partyInfo.getPartyData().getPartyId() == nowPartyId) {
                                if (i + 1 < partyList.size()) {
                                    findPartyInfo = partyList.get(i + 1);
                                    isFind = true;
                                }
                                break;
                            }
                        }
                        if (isFind) {
                            break;
                        }
                    }
                }

            } else {//指定等级
                List<CrossZhenHuanPartyInfo> partyList = getPartyListByLevel(levelNeed, isNeedFull, userId);
                if (!partyList.isEmpty()) {
                    findPartyInfo = partyList.get(0); //先默认第一场
                }
                //找到nowPartyId的后面一场
                if (nowPartyId > 0) {
                    for (int i = 0; i < partyList.size(); i++) {
                        CrossZhenHuanPartyInfo partyInfo = partyList.get(i);
                        if (partyInfo.getPartyData().getPartyId() == nowPartyId) {
                            if (i + 1 < partyList.size()) {
                                findPartyInfo = partyList.get(i + 1);
                            }
                            break;
                        }
                    }
                }
            }
        } else {//在某个人的宴会里找下一场
            List<Long> userPartyIdList = getUserPartyIdList(targetUserId);
            List<CrossZhenHuanPartyInfo> targetPartyList = new ArrayList<>();
            for (int i = 0; i < userPartyIdList.size(); i++) {
                long partyId = userPartyIdList.get(i);
                CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
                if (partyInfo.isFinish()) {
                    continue;
                }
                if (partyInfo.isTimeEnd()) {
                    continue;
                }
                if (levelNeed > 0 && partyInfo.getPartyData().getLevel() != levelNeed) {
                    continue;
                }
                if (isNeedFull && partyInfo.isFull(config.getPartyCanJoinNum())) {
                    continue;
                }

                if (partyInfo.getPartyData().getUserId() != targetUserId) {//只找举办的
                    continue;
                }

                if (partyInfo.isUserJoin(userId)) {//已经参加过了
                    continue;
                }

                targetPartyList.add(partyInfo);
            }

            if (!targetPartyList.isEmpty()) {
                findPartyInfo = targetPartyList.get(0); //先默认第一场
            }

            for (int i = 0; i < targetPartyList.size(); i++) {
                CrossZhenHuanPartyInfo partyInfo = targetPartyList.get(i);
                if (partyInfo.getPartyData().getPartyId() == nowPartyId) {
                    if (i + 1 < targetPartyList.size()) {
                        findPartyInfo = targetPartyList.get(i + 1);
                    }
                    break;
                }
            }
        }

        if (findPartyInfo == null) {
            respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_NOT_PARTY_FIND);
        } else if (findPartyInfo.getPartyId() == nowPartyId) {
            respMsg.setRet(GameErrorCode.E_ZHENHUAN_SECOND_PROCESS_NEXT_PARTY_EMPTY);
        } else {
            ZhenHuanProto.ZhenHuanSecondProcessPartyDetailTemp.Builder detailInfo = parsePartyDetailInfo(findPartyInfo);
            respMsg.setPartyDetail(detailInfo);
        }

        MessageHelper.sendPacket(serverId, userId, YanQuMessageUtils.buildMessage(ClientProtocol.U_ZHENHUAN_SECOND_PROCESS_NEXT_PARTY, respMsg));
    }

    public void debugByCmd(long playerId, String code, String param) {
        ZhenHuanSecondProcessConfig config = getConfig();
        if (code.equals("/zh2-npc")) {//往目标玩家未满的宴会填充NPC
            int num = Integer.valueOf(param);
            List<Long> userPartyIdList = getUserPartyIdList(playerId);
            for (Long partyId : userPartyIdList) {
                CrossZhenHuanPartyInfo partyInfo = getPartyInfo(partyId);
                if (partyInfo.isFinish()) {
                    continue;
                }
                if (partyInfo.isTimeEnd()) {
                    continue;
                }
                if (partyInfo.isFull(getConfig().getPartyCanJoinNum())) {
                    continue;
                }
                partyInfo.fillNpc(config, num);
            }

        }
    }
}
